package at.codebase.web.servlets.api;

import java.util.ArrayList;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import com.googlecode.objectify.Key;

import at.codebase.core.search.ItemSearch;
import at.codebase.core.search.ItemSearchResult;
import at.codebase.core.search.ItemSearchResultInfo;
import at.codebase.core.search.SortOption;
import at.codebase.core.search.SortOption.SortOptionDetail;
import at.codebase.core.search.SortOption.SortOptionType;
import at.codebase.db.entities.EImage;
import at.codebase.db.entities.EUser;
import at.codebase.web.util.LocalRequest.RequestInformation;
import at.codebase.web.util.URLParameters;
import at.codebase.web.util.URLParameters.ParameterException;
import at.codebase.web.util.servlet.ApiSecureServlet;



public class SearchAPIServlet extends ApiSecureServlet {

	@SuppressWarnings({ "unchecked", "boxing" })
	@Override
	protected JSONObject processRequest(RequestInformation requestInfo, String authToken) {
		
		URLParameters parameters = requestInfo.getParameters();
		
		try {
			String query = parameters.getString("query");
			int limit = parameters.getInteger("limit");
			int offset = parameters.getInteger("offset");
			//google_account_id will not be implemented because of missing authorization
			
			JSONArray sortOptions = null;
			try {
				String sortOptionsInput = parameters.getString("sort_options");
				sortOptions = (JSONArray) JSONValue.parse(sortOptionsInput);
			} catch (ParameterException e){	}
			
			
			ItemSearchResultInfo resultInfo = null;
			
			if(sortOptions != null && sortOptions.size() > 0){
				//Sorted search
				ArrayList<SortOption> searchSortOptions = new ArrayList<SortOption>();
				for(int i = 0; i < sortOptions.size(); i++){
					
					SortOptionType type = null;
					SortOptionDetail detail = null;
					
					JSONObject sortInfo = null;
					
					sortInfo = (JSONObject) sortOptions.get(i);

					if(sortInfo != null){
						String sortInfoType = (String) sortInfo.get("type");
						String sortInfoOrdering = (String) sortInfo.get("ordering");
						
						if(sortInfoType.equals("title")){
							type = SortOptionType.TITLE;
						}else if(sortInfoType.equals("price")){
							type = SortOptionType.PRICE;
						}else if(sortInfoType.equals("time_create")){
							type = SortOptionType.TIME_CREATE;
						}else if(sortInfoType.equals("location")){
							type = SortOptionType.LOCATION;
						}else if(sortInfoType.equals("description")){
							type = SortOptionType.DESCRIPTION;
						}
						
						if(sortInfoOrdering.equals("asc")){
							detail = SortOptionDetail.ASCENDING;
						}else if(sortInfoOrdering.equals("desc")){
							detail = SortOptionDetail.DESCENDING;
						}
						
					}
					
					if(type != null && detail != null){
						searchSortOptions.add(new SortOption(type, detail));
					}
					
				}
				resultInfo = ItemSearch.searchSorted(query, limit, offset, searchSortOptions);
			}else{
				//Unsorted search
				resultInfo = ItemSearch.search(query, limit, offset);
			}
			
			if(resultInfo != null){
				JSONObject result = successResult();
				result.put("total", resultInfo.getCount());
				
				JSONArray items = new JSONArray();
				for(ItemSearchResult itemSearchResult:resultInfo.getResults()){
					JSONObject item = new JSONObject();
					item.put("id", itemSearchResult.getItem().getId());
					item.put("title", itemSearchResult.getItem().getTitle());
					item.put("description", itemSearchResult.getDescriptionSnippet());
					
					
						JSONObject sellerObj = new JSONObject();
						EUser userSeller = itemSearchResult.getItem().getSeller().get();
						sellerObj.put("id", userSeller.getId());
						sellerObj.put("username", userSeller.getUsername());
					item.put("seller", sellerObj);
					item.put("sponsoredItems", new JSONArray());
					
					ArrayList<Key<EImage>> images = itemSearchResult.getItem().getImageKeys();
					if (images.size() > 0) {
						item.put("image", requestInfo.getHostUrl()+"/service/image?id=" + images.get(0).getId() + "&w=110&h=110");
					} else {
						item.put("image", "");
					}
					
					item.put("price", itemSearchResult.getItem().getPrice()+" USD");
					item.put("url", requestInfo.getHostUrl()+"/item/"+itemSearchResult.getItem().getId());
					
					items.add(item);
				}
				
				result.put("items", items);
				return result;
			}

			return badRequestResult("Bad search query");
			
		} catch (ParameterException e) {
			return badRequestResult("Parameters invalid");
		}
		
	}

}
